#include <iostream>
#include <conio.h>
#include <string>
#include <fstream>
#include <windows.h>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;

class Snakebody {
public:
	int x;
	int y;
};

// 全局变量
int highest_score = 0;
int current_score = 0;
int speed = 200; // 初始速度，值越小越快
int speed_level = 1; // 速度等级：1-正常，2-加速，3-减速
int food_score = 1; // 吃到食物的基础得分

void printmap(const vector<vector<string>>& map) {
	for (int i = 0; i < 30; i++) {
		for (int j = 0; j < 30; j++) {
			cout << map[i][j];
		}
		cout << endl;
	}
}
void welcome() {
	cout << "\n\n";
	cout << "1. 开始游戏" << endl;
	cout << "2. 显示最高分" << endl;
	cout << "3. 游戏说明" << endl;
	cout << "4. 退出游戏" << endl;
	cout << "请选择: ";
}
void createmap(vector<vector<string>>& map) {
	// 创建地图
	for (int i = 0; i < 30; i++) {
		for (int j = 0; j < 30; j++) {
			if (i == 0 || i == 29 || j == 0 || j == 29) {
				map[i][j] = "■";
			}
			else {
				map[i][j] = "□";
			}
		}
	}
}
void printsnake(Snakebody* snake, string** map, int snake_length) {
	//打印蛇

	for (int i = 1;i < snake_length;i++) {
		map[snake[i].y][snake[i].x] = "■";
	}
	map[snake[0].y][snake[0].x] = "●";
}
void initsnake(vector<Snakebody>& snake) {
	snake.clear();
	// 初始化蛇身，长度为3
	snake.push_back({ 15, 15 }); // 蛇头
	snake.push_back({ 15, 16 });
	snake.push_back({ 15, 17 }); // 蛇尾
}

void createfood(vector<vector<string>>& map, int& food_x, int& food_y, const vector<Snakebody>& snake) {
	// 创建食物
	srand(time(NULL));
	bool valid = false;
	while (!valid) {
		food_x = rand() % 28 + 1;
		food_y = rand() % 28 + 1;
		valid = true;
		// 检查食物是否与蛇身重叠
		for (const auto& body : snake) {
			if (body.x == food_x && body.y == food_y) {
				valid = false;
				break;
			}
		}
	}
	map[food_y][food_x] = "★";
}

bool biteself(const vector<Snakebody>& snake) {
	// 检查蛇头是否碰到身体
	for (size_t i = 1; i < snake.size(); i++) {
		if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
			return true;
		}
	}
	return false;
}

bool cantcrosswall(const Snakebody& head) {
	// 检查是否撞墙
	return (head.x <= 0 || head.x >= 29 || head.y <= 0 || head.y >= 29);
}

void speedup() {
	if (speed > 50) {
		speed -= 30; // 加速
		speed_level = 2; // 加速状态
		food_score = 2; // 加速时得2分
	}
}

void speeddown() {
	if (speed < 350) {
		speed += 30; // 减速
		speed_level = 3; // 减速状态
		food_score = 1; // 减速时得1分
	}
}

void reset_speed() {
	speed = 200; // 恢复正常速度
	speed_level = 1; // 正常状态
	food_score = 1; // 正常得1分
}
void snakemove(vector<Snakebody>& snake, int direction, bool& eat_food, int food_x, int food_y) {
	// 移动蛇
	Snakebody new_head = snake[0];
	switch (direction) {
	case 1: // 上
		new_head.y--;
		break;
	case 2: // 下
		new_head.y++;
		break;
	case 3: // 左
		new_head.x--;
		break;
	case 4: // 右
		new_head.x++;
		break;
	}

	// 检查是否吃到食物
	eat_food = (new_head.x == food_x && new_head.y == food_y);

	// 移动蛇身
	for (int i = snake.size() - 1; i > 0; i--) {
		snake[i] = snake[i - 1];
	}
	snake[0] = new_head;

	// 如果吃到食物，增加蛇身长度
	if (eat_food) {
		snake.push_back(snake.back());
		current_score += food_score;
		// 吃到食物自动加速
		speedup();
	}
}

void keyboardControl(int& direction, bool& gameover_flag) {
	// 使用 GetAsyncKeyState 检测按键状态
	// 检查按键是否被按下（高位被设置）

	if (GetAsyncKeyState(VK_UP) & 0x8000) {
		if (direction != 2) direction = 1;  // 不能直接反向移动
	}
	
	if (GetAsyncKeyState(VK_DOWN) & 0x8000) {
		if (direction != 1) direction = 2;
	}
	
	if (GetAsyncKeyState(VK_LEFT) & 0x8000) {
		if (direction != 4) direction = 3;
	}
	
	if (GetAsyncKeyState(VK_RIGHT) & 0x8000) {
		if (direction != 3) direction = 4;
	}
	// F1加速
	if (GetAsyncKeyState(VK_F1) & 0x8000) {
		speedup();
		current_score += 2;  // 加速时额外加2分
	}
	// F2减速
	if (GetAsyncKeyState(VK_F2) & 0x8000) {
		speeddown();
		if (current_score >= 2) {
			current_score -= 2;  // 减速时减2分
		}
		else {
			current_score = 0;
		}
	}
	// ESC退出
	if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
		gameover_flag = true;
	}
}
void clearKeyboardBuffer() {
	// 清空键盘缓冲区
	while (_kbhit()) _getch();
}

void scoreandtips() {
	cout << "当前得分: " << current_score << endl;
	cout << "最高得分: " << highest_score << endl;
	cout << "速度状态: ";
	switch (speed_level) {
	case 1:
		cout << "正常";
		break;
	case 2:
		cout << "加速";
		break;
	case 3:
		cout << "减速";
		break;
	}
	cout << endl;
	cout << "使用上下左右控制方向，F1加速(+2分)，F2减速(-2分)，ESC退出" << endl;
}
void File_out() {
	// 读取最高分
	ifstream fin("score.txt");
	if (fin) {
		fin >> highest_score;
		fin.close();
	}
}

void File_in() {
	// 写入最高分
	if (current_score > highest_score) {
		highest_score = current_score;
		ofstream fout("score.txt");
		if (fout) {
			fout << highest_score;
			fout.close();
		}
	}
}

void gameover() {
	File_in();
	clearKeyboardBuffer();
	system("cls");
	cout << "====================================" << endl;
	cout << "           游戏结束！" << endl;
	cout << "====================================" << endl;

	if (current_score > highest_score) {
		cout << "   创纪录啦！新纪录: " << current_score << "分" << endl;
	}
	else if (current_score == highest_score && highest_score != 0) {
		cout << "   平了最高纪录: " << highest_score << "分" << endl;
	}
	else {
		cout << "   继续努力吧！" << endl;
		cout << "   你离最高分还差 " << highest_score - current_score << " 分" << endl;
	}

	cout << "====================================" << endl;
	cout << "   你的得分: " << current_score << endl;
	cout << "   最高分: " << highest_score << endl;
	cout << "====================================" << endl;
	cout << "   1. 重新开始" << endl;
	cout << "   2. 退出游戏" << endl;
	cout << "====================================" << endl;
	cout << "请选择: ";

	int choice;
	while (true) {
		cin >> choice;
		if (choice == 1 || choice == 2) {
			break;
		}
		cout << "输入错误，请重新选择(1或2): ";
		cin.clear(); // 清除输入错误状态
	}

	if (choice == 1) {
		current_score = 0;
		speed = 200;
		speed_level = 1;
		food_score = 1;
	}
	else {
		exit(0);
	}
}
void explation() {
    system("cls");
    cout << "====================================" << endl;
    cout << "           游戏说明" << endl;
    cout << "====================================" << endl;
    cout << "1. 使用(上)、(左)、(下)、(右)键控制蛇的移动方向" << endl;
    cout << "2. 吃到食物(★)后蛇会变长，得分增加" << endl;
    cout << "   - 正常速度: 得1分" << endl;
    cout << "   - 加速状态: 得2分" << endl;
    cout << "   - 减速状态: 得1分" << endl;
    cout << "3. 按F1键可以加速(+2分)" << endl;
    cout << "4. 按F2键可以减速(-2分)" << endl;
    cout << "5. 碰到墙壁或自己的身体游戏结束" << endl;
    cout << "6. 按ESC键可以随时退出游戏" << endl;
    cout << "====================================" << endl;
    cout << "按任意键返回..." << endl;
    _getch();
}

void welcometogame() {
	clearKeyboardBuffer();
    int choice;
    do {
        system("cls");
		welcome();
		while (true) {
			if (_kbhit()) {  // 只有在有按键时才读取
				choice = _getch() - '0';  // 将字符转换为数字
				if (choice >= 1 && choice <= 4) {
					break;
				}
			}
			Sleep(100);  // 避免CPU占用过高
		}
        switch (choice) {
        case 1: {
            // 初始化游戏
            vector<vector<string>> map(30, vector<string>(30));
            vector<Snakebody> snake;
            initsnake(snake);
            createmap(map);
            int food_x, food_y;
            createfood(map, food_x, food_y, snake);
            int direction = 1; // 初始方向向上
            bool gameover_flag = false;

            // 游戏主循环
            while (!gameover_flag) {
                // 更新地图
                createmap(map);
                // 绘制蛇
                for (size_t i = 0; i < snake.size(); i++) {
                    if (i == 0) {
                        map[snake[i].y][snake[i].x] = "●"; // 蛇头
                    }
                    else {
                        map[snake[i].y][snake[i].x] = "■"; // 蛇身
                    }
                }
                // 绘制食物
                map[food_y][food_x] = "★";

                // 显示
                printmap(map);
                scoreandtips();
                // 控制
                keyboardControl(direction, gameover_flag);

                // 移动
                bool eat_food = false;
                snakemove(snake, direction, eat_food, food_x, food_y);

                // 检查是否吃到食物
                if (eat_food) {
                    createfood(map, food_x, food_y, snake);
                }

                // 检查游戏结束条件
                if (cantcrosswall(snake[0]) || biteself(snake)) {
                    gameover_flag = true;
                }

                // 控制游戏速度
				// 改为固定短延迟 + 动态速度控制
				int frame_delay = max(50, speed); // 最低延迟50ms
				Sleep(frame_delay);
            }
            gameover();
            break;
        }
        case 2: {
            File_out();
            system("cls");
            cout << "====================================" << endl;
            cout << "          当前最高分" << endl;
            cout << "====================================" << endl;
            cout << "     最高分: " << highest_score << endl;
            cout << "====================================" << endl;
            cout << "按任意键返回..." << endl;
            _getch();
            break;
        }
        case 3:
            explation();
            break;
        case 4:
            exit(0);
        default:
            cout << "无效选择，请重新输入!" << endl;
            Sleep(1000);
            break;
        }
    } while (choice != 4);
}

int main() {
    // 设置随机种子
    srand(time(NULL));
    // 读取最高分
    File_out();
    // 进入欢迎界面
    welcometogame();
    return 0;
}